package com.ilearn.limiter.intercepter;

import com.alibaba.fastjson.JSON;
import com.ilearn.limiter.enums.ResponseEnum;
import com.ilearn.limiter.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author: lyndon
 * @version: 1.0
 * @date: 2019/3/19
 */
@Slf4j
public abstract class AbstractInterceptor extends HandlerInterceptorAdapter {

    protected AbstractInterceptor() {
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        ResponseEnum calcLimit;

        try {
            calcLimit = preFilter(request);
        } catch (Exception e) {
            log.error("preFilter 得到一个异常: {}", e.getMessage());
            handleResponse(request, response);
            return false;
        }

        if (calcLimit.getCode() == 200) {
            return true;
        }

        // 失败拦截返回限流结果提示
        handleResponse(request, response);
        return false;
    }

    /**
     * 抽象拦截方法
     *
     * @param request 接收的请求
     * @return 响应体 HttpServletResponse
     */
    protected abstract ResponseEnum preFilter(HttpServletRequest request);


    private void handleResponse(HttpServletRequest request, HttpServletResponse response) {

        boolean requestIsWait = true;
        Integer requestWaitTime = 10;
        log.warn("request has been flow control.");
        HttpServletResponse resp = (HttpServletResponse) response;

        resp.setContentType("application/json;charset=UTF-8");
        resp.setStatus(401);
        if (requestIsWait) {
            resp.addHeader("Retry-After", requestWaitTime.toString());
        }
        try {
            resp.getOutputStream().write(JSON.toJSONString(ResultUtil.error(ResponseEnum.RATE_LIMIT)).getBytes("UTF-8"));
        } catch (IOException e) {
            log.error("RequestId:{} 发生IO异常.", e.getMessage());
        }
    }

}
